From bdf73da2d2cd64cb90afb567b80aae7014c19871 Mon Sep 17 00:00:00 2001 From: "Mr. E23" Date: Thu, 11 Dec 2003 20:16:34 +0000 Subject: [PATCH] The purpose of this modification is to ensure that every normal request execution starts and ends in wiki.phtml, giving the code a somewhat more predictable flow. OutputPage.php: * Added disable() method to Output class. * Replaced exit() call in checkLastModified() with "return true" (thereby altering its contract quite severly). * reportTime() now only returns elapsed time, code with side effects moved to logProfilingData() in GlobalFunctions.php. GlobalFunctions.php: * Added function logProfilingData() which does most of what OutputPage->reportTime() used to do. Article.php: * Replaced exit() in checkLastModified() with "return true" (thereby altering its contract quite severly). * replaced implicit exit in calls to checkLastModified() and tryFileCache() with returns. LogPage.php: * replaced implicit exit() with return in call to checkLastModified() SpecialRecentchanges.php: * replaced implicit exit() with return in call to checkLastModified() wiki.phtml: * Single call to logProfilingData() at the end of the request. --- includes/Article.php | 25 +++++++++++++------- includes/GlobalFunctions.php | 38 ++++++++++++++++++++++++++++--- includes/LogPage.php | 5 +++- includes/OutputPage.php | 38 ++++++++++++------------------- includes/SpecialRecentchanges.php | 5 +++- wiki.phtml | 3 ++- 6 files changed, 77 insertions(+), 37 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index dc654eee66..53e622122f 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -295,10 +295,13 @@ class Article { return; } - if ( !isset( $oldid ) ) { - if( $this->checkTouched() ) { - $wgOut->checkLastModified( $this->mTouched ); - $this->tryFileCache(); + if ( !isset( $oldid ) and $this->checkTouched() ) { + if( $wgOut->checkLastModified( $this->mTouched ) ){ + return; + } else if ( $this->tryFileCache() ) { + # tell wgOut that output is taken care of + $wgOut->disable(); + return; } } @@ -320,6 +323,7 @@ class Article { $s = wfMsg( "redirectedfrom", $redir ); $wgOut->setSubtitle( $s ); } + $wgLinkCache->preFill( $this->mTitle ); $wgOut->addWikiText( $text ); @@ -598,7 +602,10 @@ class Article { # If page hasn't changed, client can cache this - $wgOut->checkLastModified( $this->getTimestamp() ); + if( $wgOut->checkLastModified( $this->getTimestamp() ) ){ + # Client cache fresh and headers sent, nothing more to do. + return; + } $fname = "Article::history"; wfProfileIn( $fname ); @@ -1191,7 +1198,10 @@ class Article { } /* Caching functions */ - + + # checkLastModified returns true iff it has taken care of all + # output to the client that is necessary for this request. + # (that is, it has sent a cached version of the page) function tryFileCache() { static $called = false; if( $called ) { @@ -1211,8 +1221,7 @@ class Article { global $wgOut; wfDebug( " tryFileCache() - about to load\n" ); $cache->loadFromFileCache(); - $wgOut->reportTime(); # For profiling - wfAbruptExit(); + return true; } else { wfDebug( " tryFileCache() - starting buffer\n" ); if($cache->useGzip() && wfClientAcceptsGzip()) { diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index f0641a1add..5bb1f7da59 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -153,6 +153,36 @@ function wfDebug( $text, $logonly = false ) } } +function logProfilingData() +{ + global $wgRequestTime, $wgDebugLogFile; + global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser; + list( $usec, $sec ) = explode( " ", microtime() ); + $now = (float)$sec + (float)$usec; + + list( $usec, $sec ) = explode( " ", $wgRequestTime ); + $start = (float)$sec + (float)$usec; + $elapsed = $now - $start; + if ( "" != $wgDebugLogFile ) { + $prof = wfGetProfilingOutput( $start, $elapsed ); + if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) + $forward = " forwarded for " . $_SERVER['HTTP_X_FORWARDED_FOR']; + if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) + $forward .= " client IP " . $_SERVER['HTTP_CLIENT_IP']; + if( !empty( $_SERVER['HTTP_FROM'] ) ) + $forward .= " from " . $_SERVER['HTTP_FROM']; + if( $forward ) + $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; + if($wgUser->getId() == 0) + $forward .= " anon"; + $log = sprintf( "%s\t%04.3f\t%s\n", + gmdate( "YmdHis" ), $elapsed, + urldecode( $_SERVER['REQUEST_URI'] . $forward ) ); + error_log( "TJOHEJ". $log . $prof, 3, $wgDebugLogFile ); + } +} + + function wfReadOnly() { global $wgReadOnlyFile; @@ -385,9 +415,11 @@ function wfAbruptExit(){ $wgAbruptExitCalled = true; $bt = debug_backtrace(); - $file = $bt[0]["file"]; - $line = $bt[0]["line"]; - wfDebug("WARNING: Abrupt exit in $file at line $line\n"); + for($i = 0; $i < count($bt) ; $i++){ + $file = $bt[$i]["file"]; + $line = $bt[$i]["line"]; + wfDebug("WARNING: Abrupt exit in $file at line $line\n"); + } exit(); } diff --git a/includes/LogPage.php b/includes/LogPage.php index db047b2a1b..0faeab679e 100644 --- a/includes/LogPage.php +++ b/includes/LogPage.php @@ -142,7 +142,10 @@ class LogPage { function showAsDisabledPage( $rawhtml = true ) { global $wgLang, $wgOut; - $wgOut->checkLastModified( $this->getTimestamp() ); + if( $wgOut->checkLastModified( $this->getTimestamp() ) ){ + # Client cache fresh and headers sent, nothing more to do. + return; + } $func = ( $rawhtml ? "addHTML" : "addWikiText" ); $wgOut->$func( "

" . wfMsg( "perfdisabled" ) . "

\n\n" . diff --git a/includes/OutputPage.php b/includes/OutputPage.php index ab2c72d675..492733c948 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -13,6 +13,7 @@ class OutputPage { var $mDTopen, $mLastSection; # Used for processing DL, PRE var $mLanguageLinks, $mSupressQuickbar; var $mOnloadHandler; + var $mDoNothing; function OutputPage() { @@ -27,6 +28,7 @@ class OutputPage { $this->mLanguageLinks = array(); $this->mCategoryLinks = array() ; $this->mAutonumber = 0; + $this->mDoNothing = false; } function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; } @@ -38,6 +40,10 @@ class OutputPage { function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } function addLink( $rel, $rev, $target ) { array_push( $this->mLinktags, array( $rel, $rev, $target ) ); } + # checkLastModified tells the client to use the client-cached page if + # possible. If sucessful, the OutputPage is disabled so that + # any future call to OutputPage->output() have no effect. The method + # returns true iff cache-ok headers was sent. function checkLastModified ( $timestamp ) { global $wgLang, $wgCachePages, $wgUser; @@ -74,8 +80,8 @@ class OutputPage { header( "Cache-Control: private, must-revalidate, max-age=0" ); header( "Last-Modified: {$lastmod}" ); wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false ); - $this->reportTime(); # For profiling - wfAbruptExit(); + $this->disable(); + return true; } else { wfDebug( "READY client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false ); $this->mLastModified = $lastmod; @@ -98,6 +104,7 @@ class OutputPage { function isPrintable() { return $this->mPrintable; } function setOnloadHandler( $js ) { $this->mOnloadHandler = $js; } function getOnloadHandler() { return $this->mOnloadHandler; } + function disable() { $this->mDoNothing = true; } function getLanguageLinks() { global $wgTitle, $wgLanguageCode; @@ -225,7 +232,9 @@ class OutputPage { { global $wgUser, $wgLang, $wgDebugComments, $wgCookieExpiration; global $wgInputEncoding, $wgOutputEncoding, $wgLanguageCode; - + if( $this->mDoNothing ){ + return; + } $fname = "OutputPage::output"; wfProfileIn( $fname ); @@ -310,10 +319,11 @@ class OutputPage { $wgOutputEncoding = $wgInputEncoding; } + # Returns a HTML comment with the elapsed time since request. + # This method has no side effects. function reportTime() { - global $wgRequestTime, $wgDebugLogFile; - global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser; + global $wgRequestTime; list( $usec, $sec ) = explode( " ", microtime() ); $now = (float)$sec + (float)$usec; @@ -321,24 +331,6 @@ class OutputPage { list( $usec, $sec ) = explode( " ", $wgRequestTime ); $start = (float)$sec + (float)$usec; $elapsed = $now - $start; - - if ( "" != $wgDebugLogFile ) { - $prof = wfGetProfilingOutput( $start, $elapsed ); - if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) - $forward = " forwarded for " . $_SERVER['HTTP_X_FORWARDED_FOR']; - if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) - $forward .= " client IP " . $_SERVER['HTTP_CLIENT_IP']; - if( !empty( $_SERVER['HTTP_FROM'] ) ) - $forward .= " from " . $_SERVER['HTTP_FROM']; - if( $forward ) - $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; - if($wgUser->getId() == 0) - $forward .= " anon"; - $log = sprintf( "%s\t%04.3f\t%s\n", - gmdate( "YmdHis" ), $elapsed, - urldecode( $_SERVER['REQUEST_URI'] . $forward ) ); - error_log( $log . $prof, 3, $wgDebugLogFile ); - } $com = sprintf( "", $elapsed ); return $com; diff --git a/includes/SpecialRecentchanges.php b/includes/SpecialRecentchanges.php index 1e3a93de3f..9fce1a5005 100644 --- a/includes/SpecialRecentchanges.php +++ b/includes/SpecialRecentchanges.php @@ -17,7 +17,10 @@ function wfSpecialRecentchanges( $par ) $sql = "SELECT MAX(rc_timestamp) AS lastmod FROM recentchanges"; $res = wfQuery( $sql, DB_READ, $fname ); $s = wfFetchObject( $res ); - $wgOut->checkLastModified( $s->lastmod ); + if( $wgOut->checkLastModified( $s->lastmod ) ){ + # Client cache fresh and headers sent, nothing more to do. + return; + } $rctext = wfMsg( "recentchangestext" ); diff --git a/wiki.phtml b/wiki.phtml index d30db092be..5141de3adf 100644 --- a/wiki.phtml +++ b/wiki.phtml @@ -98,5 +98,6 @@ if ( Namespace::getSpecial() == $wgTitle->getNamespace() ) { $wgOut->output(); foreach ( $wgDeferredUpdateList as $up ) { $up->doUpdate(); } - +logProfilingData(); +wfDebug( "Request ended normally\n" ); ?> -- 2.20.1